package br.schindler.android.wallpaper.milkyway;

import java.io.IOException;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import br.schindler.games.android.gl.base.GLColor;
import br.schindler.games.android.gl.base.GLModel;
import br.schindler.games.android.gl.base.glut.GLUTUtils;

public class Planet  {
	
	/**
	 *Planet to be painted 
	 */
	private CelestialBody planet;	
	
	private Planet satelite = null;

	private GLColor color;
	
	protected static GLModel sphere = null;	
	
	private int texture = -1;
	
	private boolean showOrbit = true;
	
	private FloatBuffer vetzOrbit = null;


	/**
	 * Creates a new planet
	 * @param body
	 * @throws IOException 
	 */
	public Planet(CelestialBody body, Context context, GLColor c) throws IOException{
		planet = body;
		color  = c;
		
		if (sphere == null) {
			sphere = new GLModel(context, "sphere.obj");
		}	
		
		if(null == c)
			color = new GLColor(1,1,1);
		
		if (null != body.getSatellite())
			satelite = new Planet(body.getSatellite(), context, null);
	}
	
	/**
	 * Binds planet texture
	 * @param id
	 */
	public void setTexture(int id){
		texture = id;
		sphere.addTexture(id);
	}
	
	/**
	 * 
	 * @param gl
	 */
	static public void start(GL10 gl){
		sphere.Init(gl);
	}

	/**
	 * 
	 * @param gl
	 */
	static public void load(){
	    sphere.loadTextures();
	}
	
	/**
	 * 
	 * @param gl
	 * @param t
	 */
	public void drawFrame(GL10 gl, float t) { 
	 
    	double [] s = planet.currentLocation(t);
    	
        gl.glPushMatrix();
        
        gl.glTranslatef((float)s[0], (float)s[2], (float)s[1]);    
        gl.glRotatef(-t * (360f / ((float)planet.getRatation())), 0.0f, 1.0f, 0.0f);
        gl.glScalef((float) planet.getRadius(),(float) planet.getRadius(),(float) planet.getRadius());
        
       // if(texture < 0)
       //   color.apply(gl);
        
        sphere.draw(gl, texture);
        
    	gl.glPopMatrix();
        
        int P = (int) Math.round(planet.getOrbitPeriod());
 
        if (P>0 && showOrbit && (vetzOrbit != null)){
            vetzOrbit.position(0);
	        gl.glColor4f(1f, 1f, 1f, 1f);
	        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vetzOrbit);
	        gl.glDisable(GL10.GL_LIGHTING);
	        gl.glLineWidth(.2f);
	        gl.glDrawArrays(GL10.GL_LINES, 0, P*2);
	        gl.glEnable(GL10.GL_LIGHTING);
	        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        }      
        
        if (null != satelite)
        	 satelite.drawFrame(gl, t);
	}
	
	/**
	 * 
	 * @return
	 */
	public boolean isShowOrbit() {
		return showOrbit;
	}

	/**
	 * 
	 * @param showOrbit
	 */
	public void setShowOrbit(boolean showOrbit) {
		this.showOrbit = showOrbit;
		
        int P = (int) Math.round(planet.getOrbitPeriod());
        
        if (P>0 && showOrbit && (this.vetzOrbit == null)){
            int i; 
            double [] s;
            vetzOrbit = GLUTUtils.allocateFloatBuffer((P*2) * 6 * 4);
            vetzOrbit.position(0);
            for(i = 1; i <= (P); i++) {
            	s = planet.currentLocation(i);            	
            	GLUTUtils.addVertex3f(vetzOrbit, (float)s[0], (float)s[2], (float)s[1]);            
            	s = planet.currentLocation(i-1);            	
            	GLUTUtils.addVertex3f(vetzOrbit, (float)s[0], (float)s[2], (float)s[1]);
            }
        }
		
	/*	if(null!=satelite)
			satelite.setShowOrbit(showOrbit);*/
	}
	
	/**
	 * Returns planet informations
	 * @return {@link CelestialBody}
	 */
	public CelestialBody getInformation(){
		return this.planet;
	} 
	
	/**
	 * 
	 * @return
	 */
	public Planet getSatelite() {
		return satelite;
	}

	/**
	 * 
	 * @param satelite
	 */
	public void setSatelite(Planet satelite) {
		this.satelite = satelite;
	}
}
